package context

import (
	"context"
	"dc/util"
	jsonpath "github.com/larstos/jsonpath_go"
	"github.com/valyala/fasttemplate"
	"io"
	"strings"
)

const (
	templatePrefix = "${"
	templateSuffix = "}"
)

type Context struct {
	ctx  context.Context
	data map[string]interface{}
}

func New(data map[string]interface{}) *Context {
	return &Context{
		ctx:  context.Background(),
		data: data,
	}
}

func (c *Context) Set(key string, val any) {
	c.data[key] = val
}

func (c *Context) Get(key string) any {
	return c.data[key]
}

func (c *Context) Fork(key string, val any) *Context {
	data := map[string]interface{}{}
	for k, v := range c.data {
		data[k] = v
	}
	data[key] = val
	return &Context{
		ctx:  c.ctx,
		data: data,
	}
}

func (c *Context) FindE(path string) (interface{}, error) {
	return jsonpath.Lookup(c.data, "$."+path)
}

func (c *Context) Find(path string) interface{} {
	v, _ := c.FindE(path)
	return v
}

func (c *Context) Parse(str string) string {
	t := fasttemplate.New(str, templatePrefix, templateSuffix)
	return t.ExecuteFuncString(func(w io.Writer, tag string) (int, error) {
		return w.Write([]byte(util.ToString(c.Find(strings.TrimSpace(tag)))))
	})
}

func BuildExpr(alias, key string) string {
	return templatePrefix + alias + "." + key + templateSuffix
}
